/**
 * Copyright (c) 2016 Baozun All Rights Reserved.
 *
 * This software is the confidential and proprietary information of Baozun.
 * You shall not disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into
 * with Baozun.
 *
 * BAOZUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
 * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 * PURPOSE, OR NON-INFRINGEMENT. BAOZUN SHALL NOT BE LIABLE FOR ANY DAMAGES
 * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
 * THIS SOFTWARE OR ITS DERIVATIVES.
 *
 */
package com.discovery.darchrow.web.controller.wechat.oauth;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.httpclient.NameValuePair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.discovery.darchrow.net.URIUtil;
import com.discovery.darchrow.util.HttpClientUtil;
import com.discovery.darchrow.util.Md5Encrypt;
import com.discovery.darchrow.util.Validator;


/**
 * 测试调用由<span style="color:red">www-dev.jumbomart.cn</span>提供的:
 * <br>
 * 第三方接口登录授权
 * <br>
 * 获取用户信息
 * <br>
 * 获取access_token
 * <br>
 * 测试账号:
 * appid:NTH00001, secret:1523dc21f2Mbc5ac28b62915367fe106
 * @author dongliang.ma
 * @date 2016年11月24日上午9:45:56
 */
@Controller
public class WechatOauthTestNpController {
	
	private static final Logger log = LoggerFactory.getLogger(WechatOauthTestNpController.class);
	
	
//	private static final String DOMAIN="www-dev.jumbomart.cn";
	private static final String DOMAIN="www.jumbomart.cn";
	
//	private static final String DOMAIN="10.88.33.32";
	
	//3c-dev.jumbomart.cn
	/** 获取用户openid(隐性)*/
	private static final String SHOW_URL ="https://"+DOMAIN+"/wechat/oauth/userinfo";
	
	
	/** 获取用户openid(隐性)*/
	private static final String HIDE_URL ="https://"+DOMAIN+"/wechat/oauth/openid";
	
	
	/** 获取用户信息*/
	private static final String USER_INFO_URL ="https://"+DOMAIN+"/wechat/api/userinfo";
	
	/** 获取token*/
	private static final String ACCESS_TOKEN_URL ="https://"+DOMAIN+"/wechat/api/accesstoken";
	
	
	private static final String BACK_URL ="http://10.88.33.32:8090/oauth/call-back.htm";
	
//	private static final String BACK_URL ="http://bud-uat.chinacloudsites.cn/cny2017/";
	
	@RequestMapping(value = "/oauth/testOauth.htm", method = RequestMethod.GET)
	public String test(HttpServletRequest request, Model model) {
		
		model.addAttribute("domain", DOMAIN);
		
		return "oauth/test-oauth";
	}
	
	@RequestMapping(value = "/oauth/testShowOauth.htm", method = RequestMethod.GET)
	public String testShowOauth(
			@RequestParam(value = "appid") String appid,
			@RequestParam(value = "secret") String secret,
			@RequestParam(value = "account",required =false) Integer account,
			Model model,
			HttpServletRequest request, HttpServletResponse response) throws IOException {
		
		String uri =SHOW_URL;
		uri +="?";
		uri +="appid=" + appid;
		uri +="&";
		String callback = URIUtil.encode(BACK_URL, "UTF-8");
		uri +="callback=" + callback;
		if(Validator.isNotNullOrEmpty(account)){
			uri +="&";
			uri +="account=" + account;
		}
		
		Map<String, String> paraMap =new HashMap<String, String>();
		paraMap.put("appid", appid);
		if(Validator.isNotNullOrEmpty(account)){
			paraMap.put("account", String.valueOf(account));
		}
		
		paraMap.put("callback", callback);
		String queryStr =createLinkString(paraMap);
		String preSign =Md5Encrypt.md5(queryStr);
		String sign =Md5Encrypt.md5(preSign+secret).toUpperCase();
		uri +="&";
		uri +="sign=" + sign;
		log.debug("uri:{}", uri);
		
		return "redirect:" + uri;
	}
	
	
	@RequestMapping(value = "/oauth/testHideOauth.htm", method = RequestMethod.GET)
	public String testHideOauth(
			@RequestParam(value = "appid") String appid,
			@RequestParam(value = "secret") String secret,
			@RequestParam(value = "account",required =false) Integer account,
			Model model,
			HttpServletRequest request, HttpServletResponse response) throws IOException {
		
		String uri =HIDE_URL;
		uri +="?";
		uri +="appid=" + appid;
		uri +="&";
		uri +="callback=" + BACK_URL;
		if(Validator.isNotNullOrEmpty(account)){
			uri +="&";
			uri +="account=" + account;
		}
		
		Map<String, String> paraMap =new HashMap<String, String>();
		paraMap.put("appid", appid);
		if(Validator.isNotNullOrEmpty(account)){
			paraMap.put("account", String.valueOf(account));
		}
		
		String callback = URIUtil.encode(BACK_URL, "UTF-8");
		paraMap.put("callback", callback);
		String queryStr =createLinkString(paraMap);
		String preSign =Md5Encrypt.md5(queryStr);
		String sign =Md5Encrypt.md5(preSign+secret).toUpperCase();
		uri +="&";
		uri +="sign=" + sign;
		log.debug("uri:{}", uri);
		
		return "redirect:" + uri;
	}
	
	@RequestMapping(value = "/oauth/testGetUserInfo.json", method = RequestMethod.POST)
	@ResponseBody
	public void testGetUserInfo(
			@RequestParam(value = "appid") String appid,
			@RequestParam(value = "secret") String secret,
			@RequestParam(value = "account",required =false) Integer account,
			@RequestParam(value = "openid") String openid,
			Model model,
			HttpServletRequest request, HttpServletResponse response) throws IOException {
		
		Map<String, String> paraMap =new HashMap<String, String>();
		paraMap.put("appid", appid);
		if(Validator.isNotNullOrEmpty(account)){
			paraMap.put("account", String.valueOf(account));
		}
		paraMap.put("openid", openid);
		String queryStr =createLinkString(paraMap);
		String sign1 =Md5Encrypt.md5(queryStr);
		String sign =Md5Encrypt.md5(sign1+secret).toUpperCase();
		
		NameValuePair[] nameValuePairs =new NameValuePair[Validator.isNotNullOrEmpty(account)? 4 : 3];
		nameValuePairs[0]=new NameValuePair("appid", appid);
		if(Validator.isNotNullOrEmpty(account)){
			nameValuePairs[1]=new NameValuePair("account", String.valueOf(account));
			nameValuePairs[2]=new NameValuePair("openid", openid);
			nameValuePairs[3]=new NameValuePair("sign", sign);
		}else{
			nameValuePairs[1]=new NameValuePair("openid", openid);
			nameValuePairs[2]=new NameValuePair("sign", sign);
		}
		
		
		String res =HttpClientUtil.getPostMethodResponseBodyAsString(USER_INFO_URL, nameValuePairs);
		response.setContentType("text/html; charset=UTF-8");
		PrintWriter out = response.getWriter(); 
		out.print(res);
		out.flush();  
        out.close();
	}
	
	@RequestMapping(value = "/oauth/testGetToken.json", method = RequestMethod.POST)
	@ResponseBody
	public void testGetToken(
			@RequestParam(value = "appid") String appid,
			@RequestParam(value = "secret") String secret,
			@RequestParam(value = "account", required =false) Integer account,
			Model model,
			HttpServletRequest request, HttpServletResponse response) throws IOException {
		
		
		
		Map<String, String> paraMap =new HashMap<String, String>();
		paraMap.put("appid", appid);
		if(Validator.isNotNullOrEmpty(account)){
			paraMap.put("account", String.valueOf(account));
		}
		String queryStr =createLinkString(paraMap);
		String sign1 =Md5Encrypt.md5(queryStr);
		String sign =Md5Encrypt.md5(sign1+secret).toUpperCase();

		NameValuePair[] nameValuePairs =new NameValuePair[Validator.isNotNullOrEmpty(account)? 3 : 2];
		nameValuePairs[0]=new NameValuePair("appid", appid);
		if(Validator.isNotNullOrEmpty(account)){
			nameValuePairs[1]=new NameValuePair("account", String.valueOf(account));
			nameValuePairs[2]=new NameValuePair("sign", sign);
		}else{
			nameValuePairs[1]=new NameValuePair("sign", sign);
		}
		
		
		String res =HttpClientUtil.getPostMethodResponseBodyAsString(ACCESS_TOKEN_URL, nameValuePairs);
		response.setContentType("text/html; charset=UTF-8");
		PrintWriter out = response.getWriter(); 
		out.print(res);
		out.flush();  
        out.close();
	}
	
	
	
	
	@RequestMapping(value = "/oauth/call-back.htm", method = RequestMethod.GET)
	public String callBack(HttpServletRequest request, Model model,
			@RequestParam("openid")String openid) throws UnsupportedEncodingException {
		model.addAttribute("openid", openid);
		Map<String, String> pMap=new HashMap<String, String>();
		for (Map.Entry<String, String[]> entry :request.getParameterMap().entrySet()) {
			pMap.put(entry.getKey(), request.getParameter(entry.getKey()));
		}
		
		model.addAttribute("pMap", pMap);
		return "oauth/call-back";
	}
	
	public String createLinkString(Map<String, String> params) {

        List<String> keys = new ArrayList<String>(params.keySet());
        Collections.sort(keys);

        String prestr = "";

        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            String value = params.get(key);

            if (i == keys.size() - 1) {//拼接时，不包括最后一个&字符
                prestr = prestr + key + "=" + value;
            } else {
                prestr = prestr + key + "=" + value + "&";
            }
        }

        return prestr;
    }
	
}
